#include <iostream>
#include <stdio.h>
#include <list>

using namespace std;

//抽象访问者Visitor（访问者类）
class Apple;
class Book;
class Visitor{
public:
	void setName(string name){
		this->name = name;
	}
	
	virtual void visit(Apple *apple) = 0;
	virtual void visit(Book *book) = 0;
protected:
	string name; 
}; 

//具体访问者类Customer（顾客类） 
class Customer : public Visitor{
public:
	void visit(Apple *apple){
		cout << "顾客" << name << "选苹果。" << endl;
	}
	
	void visit(Book *book){
		cout << "顾客" << name << "买书。" << endl; 
	}
};

//具体访问者类Saler（收银员类） 
class Saler : public Visitor{
public:
	void visit(Apple *apple){
		cout << "收银员" << name << "给苹果过秤，然后计算价格。" << endl;
	}
	
	void visit(Book *book){
		cout << "收银员" << name << "直接计算书的价格。" << endl; 
	}
};

//抽象元素类Product（商品类）
class Product{
public:
	virtual void accept(Visitor *visitor) = 0;
}; 

//具体元素类Apple（苹果类） 
class Apple : public Product{
public:
	void accept(Visitor *visitor){
		visitor->visit(this);
	}
};

//具体元素类Book（书籍类） 
class Book : public Product{
public:
	void accept(Visitor *visitor){
		visitor->visit(this);
	}
};

//对象结构BuyBasket（购物车类）
class BuyBasket{
public:
	void accept(Visitor *visitor){
		for(auto i : list_){
			i->accept(visitor);
		}
	}
	
	void addProduct(Product *product){
		list_.push_back(product);
	}
	
	void removeProduct(Product *product){
		list_.remove(product);
	}
private:
	list<Product*> list_;
}; 


int main(int argv, char**argc)
{
    printf("************  test hello zc!!!   **************\n");
    /* add test code! */

	//创建商品 
	Book b1,b2;
	Apple a1;
	
	//创建购物车 
	BuyBasket basket;
	
	//购物车添加商品 
	basket.addProduct(&b1);
	basket.addProduct(&b2);
	basket.addProduct(&a1);
	
	//创建顾客 
	Customer customer;
	customer.setName("张三");
	
	//访问操作 
	basket.accept(&customer);
	
	//购物车移除商品 
	basket.removeProduct(&b2);
	
	cout << "-----------------" << endl;
	 
	//创建收银员 
	Saler saler;
	saler.setName("李四");
	
	//访问操作 
	basket.accept(&saler);

    
    return 0;
}
